﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;
using BbsbWebService.Classes;
using BbsbWebService.Enums;
using System.Threading;

namespace BbsbWebService.Repositories.Server
{
    public class ServerGroupRepository : ServerPowerRepositoryBase<Group>
    {
        public override void Initialise()
        {
            if (File.Exists(AppSettings.SettingsFile.FullName))
            {
                XDocument doc = XDocument.Load(AppSettings.SettingsFile.FullName);

                var groups = doc.Descendants("AllGroups");
                foreach (var xmlGroup in groups.Elements("Group"))
                {
                    Group group = new Group
                    {
                        Id = new Guid(xmlGroup.Element("Id").Value),
                        Name = xmlGroup.Element("Name").Value,
                        Type = GetType(xmlGroup.Element("Type"))
                    };
                    Items.Add(group);
                }
            }

        }

        public override XElement SaveRepository()
        {
            XElement groups = new XElement("AllGroups",
                from allGroup in Items
                select new XElement("Group",
                    new XElement("Id", allGroup.Id),
                    new XElement("Name", allGroup.Name),
                    new XElement("Type", allGroup.Type)
                    )
                    );

            return groups;
        }

        public override void SaveItem(Group group)
        {
            if (group.EditedGroupItems.Any())
            {
                foreach (var inItem in group.EditedGroupItems)
                {
                    // ensure item belongs to group
                    if (!inItem.Groups.Any(o => o.Id == group.Id))
                    {
                        inItem.Groups.Add(group);
                    }
                }

                IEnumerable<ControllableItem> outItems = RepositoryInstances.ItemRepository.Items.Where(o => !group.EditedGroupItems.Any(p => o.Id == p.Id));
                foreach (var item in outItems)
                {
                    // ensure item belongs to group
                    if (item.Groups.Any(o => o.Id == group.Id))
                    {
                        int index = item.Groups.GetIndexOfItem(o => o.Id == group.Id);
                        item.Groups.RemoveAt(index);
                    }
                }
            }
            base.SaveItem(group);
        }

        private static GroupType GetType(XElement xElement)
        {
            GroupType retVal = GroupType.Other;
            try
            {
                retVal = (GroupType)Enum.Parse(typeof(GroupType), xElement.Value);
            }
            catch (Exception) { }

            return retVal;
        }

        public override PowerState Toggle(Guid id)
        {
            // Do nothing, we can't toggle a group.
            return PowerState.Unknown;
        }

        protected override PowerState SendPowerBase(CommandItem item, PowerOption option)
        {
            // Loop through all items and send power...
            Group group = item as Group;
            if (group != null)
            {
                foreach (var groupItem in group.GroupItems)
                {
                    RepositoryInstances.ItemRepository.SendPower(groupItem.Id, option);
                    Thread.Sleep(100);
                }
            }

            // Groups never have a state so return unknown
            return PowerState.Unknown;
        }

        public override void UpdateState(Guid id, PowerState state)
        {
            // Do nothing...
        }
    }
}
